﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LibrarySync2.Settings;
using LibrarySync2.Business.Worker;
using System.IO;
using LibrarySync2.Common.Event;
using LibrarySync2.Common.Interfaces;
using LibrarySync2.ChildForms;
using LibrarySync2.Common.Enum;

namespace LibrarySync2.Controls
{
    public partial class ucCreateaDump : BaseUserControl
    {
        protected delegate void VerifyUpdateFilesDelegate(IFileSystemUpdate update);
        protected delegate void UpdateUIDelegate();

        LibraryComparer _comparer;
        LibraryCopier _copier;

        public ucCreateaDump()
        {
            InitializeComponent();
            LoadPreferences();
            UserPreferencesManager.PreferencesUpdated += new EventHandler<EventArgs>(UserPreferencesManager_PreferencesUpdated);
        }

        void UserPreferencesManager_PreferencesUpdated(object sender, EventArgs e)
        {
            LoadPreferences();
        }

        private void LoadPreferences()
        {
            selectorLocalLibrary.Path = UserPreferencesManager.Settings.DefaultMediaDirectory;
            selectorDestination.Path = UserPreferencesManager.Settings.DefaultDestinationDirectory;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (_copier.Running)
                _copier.Cancel();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;
            PerformComparison();
        }

        void _comparer_ComparisonEvent(object sender, ComparisonEventArgs e)
        {
            this.InvokeUpdateStatus(txtStatus, e.Message);
            if (e.Comparison != null)
                this.InvokeVerifyUpdateFiles(e.Comparison);
        }

        void InvokeVerifyUpdateFiles(IFileSystemUpdate update)
        {
            this.Invoke(new VerifyUpdateFilesDelegate(VerifyUpdateFiles), update);
        }

        protected void PerformComparison()
        {
            if (!ValidateInputs())
                return;

            var localLibraryDirectory = new DirectoryInfo(selectorLocalLibrary.Path);
            var partnerLibraryFile = new FileInfo(selectorPartnerLibraryFile.Path);
            var partnerBlacklistFile = string.IsNullOrEmpty(selectorPartnerBlacklist.Path) ?
                null :
                new FileInfo(selectorPartnerBlacklist.Path);

            _comparer = new LibraryComparer(localLibraryDirectory, partnerLibraryFile, partnerBlacklistFile, true);

            _comparer.ComparisonEvent += new EventHandler<LibrarySync2.Common.Event.ComparisonEventArgs>(_comparer_ComparisonEvent);
            _comparer.Start();
        }

        protected void VerifyUpdateFiles(IFileSystemUpdate update)
        {
            var verifyForm = new VerifyUpdateFilesForm(update);
            var dialogResult = verifyForm.ShowDialog(this);

            if (dialogResult == DialogResult.Cancel)
            {
                ResetStartButton();
                return;
            }
                
            var confirmedUpdate = verifyForm.FileSystemUpdate;

            _copier = new LibraryCopier(new DirectoryInfo(selectorDestination.Path), confirmedUpdate);
            _copier.CopyEvent += new EventHandler<CopyEventArgs>(_copier_CopyEvent);
            _copier.Start();
        }

        void _copier_CopyEvent(object sender, CopyEventArgs e)
        {
            this.InvokeUpdateStatus(txtStatus, e.Message);
            if (e.Status == CopyStatusType.Cancelled || e.Status == CopyStatusType.Complete)
                this.Invoke(new UpdateUIDelegate(ResetStartButton));
        }

        protected void ResetStartButton()
        {
            btnStart.Enabled = true;
        }

        protected bool ValidateInputs()
        {
            if (string.IsNullOrEmpty(selectorLocalLibrary.Path))
                return ShowErrorMessage("You must specify a local library.");

            var localLibrary = new DirectoryInfo(selectorLocalLibrary.Path);
            if (!localLibrary.Exists)
                return ShowErrorMessage("Specified local library does not exist.");

            if (string.IsNullOrEmpty(selectorPartnerLibraryFile.Path))
                return ShowErrorMessage("You must specify a trading partner's library file.");

            var tradingPartnerFie = new FileInfo(selectorPartnerLibraryFile.Path);
            if (!tradingPartnerFie.Exists)
                return ShowErrorMessage("Specified trading partner's library file does not exist.");

            if (!string.IsNullOrEmpty(selectorPartnerBlacklist.Path))
            {
                var partnerBlacklistFile = new FileInfo(selectorPartnerBlacklist.Path);
                if (!partnerBlacklistFile.Exists)
                    return ShowErrorMessage("Specified trading partner's blacklist file does not exist.");
            }

            if (string.IsNullOrEmpty(selectorDestination.Path))
                return ShowErrorMessage("You must specify a destination for the dump.");

            var destination = new DirectoryInfo(selectorDestination.Path);
            if (!destination.Exists)
                return ShowErrorMessage("Specified destination does not exist.");

            return true;
        }
    }
}
